Skip to content

Automated Test: sms-retry-enhanced #372

Closed
wants to merge 1 commit into from

Conversation

admin-coderabbit
Copy link
Owner

@admin-coderabbit admin-coderabbit commented Feb 4, 2026

This pull request was automatically created by @coderabbitai/e2e-reviewer.

Batch created pull request.

Summary by CodeRabbit

  • New Features
    • SMS reminders now feature automatic retry logic to track and intelligently handle failed delivery attempts, ensuring better delivery success rates
    • System automatically identifies and cleans up failed reminders when retry attempts exceed the configured threshold
    • Enhanced error handling for SMS reminder scheduling with improved recovery mechanisms to address temporary failures

* add retry count to workflow reminder

* add logic to for retry count

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
@coderabbit-eval
Copy link

coderabbit-eval bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

This PR introduces retry tracking for failed SMS reminders in workflows. A new retryCount field is added to the WorkflowReminder database model, and the scheduling logic is updated to increment retry counts on failed attempts and delete reminders after multiple failed retries.

Changes

Cohort / File(s) Summary
Database Schema & Migration
packages/prisma/schema.prisma, packages/prisma/migrations/20240508134359_add_retry_count_to_workflow_reminder/migration.sql
Adds retryCount integer field with default value 0 to the WorkflowReminder model and creates corresponding database migration.
SMS Reminder Scheduling Logic
packages/features/ee/workflows/api/scheduleSMSReminders.ts
Updates query to fetch retryCount, increments retryCount on failed SMS scheduling and caught errors, and extends delete filter to remove reminders with retryCount > 1 or past-due status.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A retry counter hops along,
When SMS sends go weak and wrong,
Delete them after tries run deep,
Persistence—that's the promise we keep! 📬

🚥 Pre-merge checks | ✅ 1 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Automated Test: sms-retry-enhanced' does not clearly describe the actual changes; it appears to be a test branch name rather than a meaningful summary of the substantive code modifications. Replace with a descriptive title that captures the main change, such as 'Add retry logic for SMS reminders with retryCount tracking' or 'Implement SMS reminder retry mechanism with failure tracking'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sms-retry-enhanced

Comment @coderabbit eval help to get the list of available commands and usage tips.

@coderabbit-eval coderabbit-eval bot closed this Feb 4, 2026
Copy link

@coderabbit-eval coderabbit-eval bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/features/ee/workflows/api/scheduleSMSReminders.ts`:
- Around line 31-43: The OR branch currently deletes any reminder with
retryCount > 1 regardless of type or schedule; narrow it so the retryCount
condition only applies to failed SMS reminders without a scheduledDate. Update
the second OR object to include method: WorkflowMethods.SMS and a constraint
that scheduledDate is absent/unscheduled (e.g., null or missing) in addition to
retryCount > 1 so only unscheduled SMS retries are targeted.
- Around line 178-186: The current updates to retryCount use a read-modify-write
pattern (retryCount: reminder.retryCount + 1) which can lose increments under
concurrent cron runs; change both prisma.workflowReminder.update calls that
reference reminder.retryCount to use Prisma's atomic increment API (data: {
retryCount: { increment: 1 } }) so updates are applied atomically via
prisma.workflowReminder.update rather than relying on the stale
reminder.retryCount value.

Comment on lines +31 to +43
OR: [
{
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
},
{
retryCount: {
gt: 1,
},
},
],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Scope retry cleanup to SMS and unscheduled reminders only.
The new OR branch (retryCount > 1) is not constrained to method: SMS, and also deletes scheduled reminders with retries, which can remove unrelated/valid reminders. Consider scoping the delete to SMS and unscheduled failed retries.

🔧 Suggested fix
-  await prisma.workflowReminder.deleteMany({
-    where: {
-      OR: [
-        {
-          method: WorkflowMethods.SMS,
-          scheduledDate: {
-            lte: dayjs().toISOString(),
-          },
-        },
-        {
-          retryCount: {
-            gt: 1,
-          },
-        },
-      ],
-    },
-  });
+  await prisma.workflowReminder.deleteMany({
+    where: {
+      method: WorkflowMethods.SMS,
+      OR: [
+        {
+          scheduledDate: {
+            lte: dayjs().toISOString(),
+          },
+        },
+        {
+          scheduled: false,
+          retryCount: {
+            gt: 1,
+          },
+        },
+      ],
+    },
+  });
🤖 Prompt for AI Agents
In `@packages/features/ee/workflows/api/scheduleSMSReminders.ts` around lines 31 -
43, The OR branch currently deletes any reminder with retryCount > 1 regardless
of type or schedule; narrow it so the retryCount condition only applies to
failed SMS reminders without a scheduledDate. Update the second OR object to
include method: WorkflowMethods.SMS and a constraint that scheduledDate is
absent/unscheduled (e.g., null or missing) in addition to retryCount > 1 so only
unscheduled SMS retries are targeted.

Comment on lines +178 to +186
} else {
await prisma.workflowReminder.update({
where: {
id: reminder.id,
},
data: {
retryCount: reminder.retryCount + 1,
},
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd scheduleSMSReminders.ts

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 206


🏁 Script executed:

wc -l packages/features/ee/workflows/api/scheduleSMSReminders.ts

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 152


🏁 Script executed:

cat -n packages/features/ee/workflows/api/scheduleSMSReminders.ts | sed -n '170,200p'

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 1028


🏁 Script executed:

cat -n packages/features/ee/workflows/api/scheduleSMSReminders.ts | head -100

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 4333


🏁 Script executed:

cat -n packages/features/ee/workflows/api/scheduleSMSReminders.ts | sed -n '1,70p' | tail -20

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 677


🏁 Script executed:

rg "increment:" packages/features/ee/workflows/ -A 2 -B 2

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 508


🏁 Script executed:

rg "retryCount.*increment" --type ts --type tsx

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 117


🏁 Script executed:

rg "increment:" -t ts -A 1 -B 1 | head -50

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 1680


🏁 Script executed:

sed -n '1,50p' packages/features/tasker/repository.ts | grep -A 10 "increment"

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 72


🏁 Script executed:

rg -n "attempts.*increment" packages/features/tasker/repository.ts -B 5 -A 5

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 520


🏁 Script executed:

cat -n packages/features/ee/workflows/api/scheduleSMSReminders.ts | sed -n '160,200p'

Repository: admin-coderabbit/coderabbit-cal_dot_com-mirror

Length of output: 1313


Replace retryCount increment with Prisma atomic operation to prevent lost updates in concurrent cron execution.

retryCount: reminder.retryCount + 1 can lose updates when multiple cron instances process the same reminder concurrently. Both instances read the same value, increment it, and persist the same final count instead of proper sequential increments. Use Prisma's atomic increment.

This occurs at lines 184 and 195.

Suggested fix
           data: {
-            retryCount: reminder.retryCount + 1,
+            retryCount: { increment: 1 },
           },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else {
await prisma.workflowReminder.update({
where: {
id: reminder.id,
},
data: {
retryCount: reminder.retryCount + 1,
},
});
} else {
await prisma.workflowReminder.update({
where: {
id: reminder.id,
},
data: {
retryCount: { increment: 1 },
},
});
🤖 Prompt for AI Agents
In `@packages/features/ee/workflows/api/scheduleSMSReminders.ts` around lines 178
- 186, The current updates to retryCount use a read-modify-write pattern
(retryCount: reminder.retryCount + 1) which can lose increments under concurrent
cron runs; change both prisma.workflowReminder.update calls that reference
reminder.retryCount to use Prisma's atomic increment API (data: { retryCount: {
increment: 1 } }) so updates are applied atomically via
prisma.workflowReminder.update rather than relying on the stale
reminder.retryCount value.

Sign in to join this conversation on GitHub.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant